#ifndef E_STRING_H
#define E_STRING_H

#include <iostream>
#include <list>
#include <vector>
#include <assert.h>
#include <DefineLibCommon.h>
#ifdef linux
#include <string.h>
#endif

class EString;
typedef std::vector<EString> EStringList;
class COMMON_DLL EString
{
public:
    EString(const char* str = "");
    
    EString(const EString& s);

    ~EString();

    const static size_t m_npos = -1;


    const char* data();
    const char* data() const;

    size_t size();
    size_t size() const;
    //change length of this string
    void reserve(size_t n);
    void swap(EString& s);

    //add a char to the end of string
    void push_back(char ch);

    //append a string to the end of string
    void append(const char* str);
    void append(const EString& str);
    //insert a char into the string
    EString& insert(size_t pos, char ch);
    //insert a string into this string
    EString& insert(size_t pos, const char* str);
    //if no parameter is given, this string will be empty
    EString& erase(size_t pos =0, size_t len = -1);
    //replace substring
    void replace(const char* subStrOld, const char* subStrNew);
    void replace(size_t pos, size_t len, const char* subStrNew);

    //remove substring, if there are more than one substring, then all substring will be removed
    void remove(const char* subStr);
    void removeLeft(size_t len);
    void removeRight(size_t len);
    //get substring by posBegin and length
    EString subStr(size_t posBegin, size_t len) const;
    //get substring frome left to right
    EString left(size_t len);
    //get substring frome right to left
    EString right(size_t len);
    //split this string into a EStringList by a substring
    EStringList split(const EString& subStr) const;

    //pos is the find start point
    int find(char ch, size_t pos = 0) const;
    int find(const char* str, size_t pos = 0) const;
    int find(const EString& s, size_t pos = 0) const;
    //charge if substring is contained in this string
    bool contains(const char* subStr) const;
    bool contains(const EString& subStr) const;

    //charge if is empty
    bool isEmpty() const;

    // EString& operator=(EString s);
    EString& operator=(const EString& s);

    EString& operator+=(const char* str);
    EString& operator+=(const EString& str);
    EString& operator+=(char ch);

    EString operator+(const char* str) const;
    EString operator+(const char* str);
    EString operator+(const EString& s);
    EString operator+(char ch);

    char& operator[](size_t pos);
    char& operator[](size_t pos) const;


    /*compare this string with other string according to ASCII
     * return 0 this==other
     * return -1 this<other
     * return 1 this>other*/
    int compare(const EString& str) const;

    /**used by map compare function, so that EString can be a map's key value*/
    bool operator<(const EString& str) const;
    bool operator>(const EString& str) const;
    bool operator==(const EString& str) const;
    bool operator!=(const EString& str) const;

    // bool operator==(const char* str);
    // bool operator==(const char* str) const;

    /**convert int value to EString*/
    static EString number(int value);
    /**convert size_t value to EString*/
    static EString number(size_t value);
    /**convert double value to EString*/
    static EString number(double value, const char* formatStr="%f");
    /**convert bool value to EString*/
    static EString boolValue(bool value);
    /**charge if a EStringList contains a EString*/
    static bool EStringListContains(const EStringList& list, const EString& str);
    /*construct EString frome std::string*/
    static EString fromStdString(const std::string& stdStr);
    /*get EStringList's print string for deuging*/
    static EString EStringListGetPrintStr(const EStringList& strList);
    
private:
    char* m_data;	
    size_t m_size;
    //size that except '\0'
    size_t m_capacity;
};


#endif
